﻿using MesBSW.DAL.MesDB;
using MesBSW.DAL.MesDTO;
using MesBSW.Tools;
using MesBSW.View;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;

namespace MesBSW.BLL.Mes
{
    public class ProdScheduleControler : BaseControler
    {
        BaseControler bs = new BaseControler();
        /// <summary>
        /// 查询工单信息
        /// </summary>
        /// <param name="prodNos">工单号</param>
        /// <returns></returns>
        public List<TargetProdProcess> SearchTargetForProdNo(List<string> prodNos)
        {
            List<TargetProdProcess> resList = new List<TargetProdProcess>();
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.TargetProdProcesses.Where(t => prodNos.Contains(t.ProdNumber));
                if (query != null && query.Count() > 0)
                {
                    resList.AddRange(query);
                }
            }
            return resList;
        }


        /// <summary>
        /// 根据工单ID号查询工单的预交期资料
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public List<SourcePPCycle> SearchSourcePPCycleForTargetID(List<int> ids)
        {
            List<SourcePPCycle> resList = new List<SourcePPCycle>();
            using(MesDB ctx = new MesDB())
            {
                var query = from a in ctx.TargetProdProcesses
                            join b in ctx.SourceProdProcesses on a.ParentID equals b.ID into res1
                            from ab in res1
                            join c in ctx.SourcePPCycle on ab.ID equals c.SourceID into res2
                            from bc in res2
                            where ids.Contains(a.ID)
                            select bc;
                if (query != null && query.Count() > 0)
                {
                    resList.AddRange(query);
                }
            }
            return resList;
        }


        /// <summary>
        /// 查询所有的交期设定
        /// </summary>
        /// <returns></returns>
        public List<ProdCycle> SearchAllProdCycle()
        {
            List<ProdCycle> resList = new List<ProdCycle>();
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.ProdCycle;
                if (query != null)
                {
                    resList.AddRange (query);
                }
            }
            return resList;
        }


        /// <summary>
        /// 新增排单计划
        /// </summary>
        /// <param name="scheduleList"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public int InsertProdSchedule(List<ProdScheduleDTO> scheduleList)
        {
            int count = 0;
            if (scheduleList != null && scheduleList.Count > 0)
            {
                //取得服务器中的当然日期时间
                DateTime tmpDay = this.GetCurrDateTime();
                using (MesDB ctx = new MesDB())
                {
                    List<string> prodList = scheduleList.Select(a => a.ProdNumber).Distinct().ToList();

                    var beginQuery = from a in ctx.ProdProcScans
                                     join b in ctx.ProdLineSettings on a.SiteInfoID equals b.BeginSiteID into res1
                                     from ab in res1
                                     where prodList.Contains(a.ProdNumber)
                                     select new { A = a, AB = ab };
                    var beginList = beginQuery.ToList();

                    var endQuery = from a in ctx.ProdProcScans
                                   join b in ctx.ProdLineSettings on a.SiteInfoID equals b.LastSiteID into res1
                                   from ab in res1
                                   where prodList.Contains(a.ProdNumber)
                                   select new { A = a, AB = ab };
                    var endList = endQuery.ToList();

                    //定义数组，用于保存小单组的工单
                    List<string> littleList = new List<string>(); 

                    foreach (var item in scheduleList)
                    {
                        ProdSchedule scheBean = new ProdSchedule();
                        EntityTools.CopyEntity<ProdScheduleDTO, ProdSchedule>(item, ref scheBean);

                        //如何是小单组的工单，将工单号放到littleList中
                        if (scheBean.LineID == 5)
                        {
                            littleList.Add(scheBean.ProdNumber);
                        }

                        //先预设工单在产线是未完成
                        scheBean.IsComp = 0;
                        scheBean.CompDate = null;
                        scheBean.CompLineID = 0;
                        if (beginList != null && beginList.Count > 0)
                        {
                            var hasQuery = beginList.Where(s => s.A.ProdProcID == item.ProdID && s.AB.ID == item.LineID);
                            if (hasQuery != null && hasQuery.Count() > 0 && item.Remark.Equals("未收到"))
                            {
                                scheBean.Remark = "";
                            }
                        }

                        //检查工单在产线尾站是否已经有扫码记录，如果有，将工单设成已完成，并取得工单的扫码时间
                        if (endList != null && endList.Count > 0)
                        {
                            var hasQuery = endList.Where(s => s.A.ProdProcID == item.ProdID && s.AB.ID == item.LineID);
                            if (hasQuery != null && hasQuery.Count() > 0)
                            {
                                scheBean.IsComp = 1;
                                scheBean.CompDate = hasQuery.First().A.ScanDate;
                            }
                        }
                        scheBean.CreateUser = MainFrm.LoginUser.user_name;
                        scheBean.CreateDate = tmpDay;

                        ctx.ProdSchedules.Add(scheBean);

                        //屏蔽生成标准交期代码，标准交期放到计算工单是否齐料的程序中，2024-11-19，THOR
                        //if ((item.LineName.ToUpper().Contains("SMT") || item.LineName.ToUpper().Contains("COB")) && item.SourcePPCycle != null && item.SourcePPCycle.ID > 0)
                        //{
                        //    ctx.SourcePPCycle.Attach(item.SourcePPCycle);
                        //    ctx.Entry<SourcePPCycle>(item.SourcePPCycle).State = System.Data.Entity.EntityState.Modified;
                        //}
                    }

                    //如果保存的计划中有小单组的计划
                    if (littleList != null && littleList.Count > 0)
                    {
                        //查询小单组计划中工单的流程和扫码记录
                        var scanQuery = from a in ctx.TargetProdProcesses
                                        join b in ctx.ProdProcSites on a.ID equals b.ProdProcID into res1
                                        from ab in res1
                                        join c in ctx.ProdProcScans on a.ID equals c.ProdProcID into res2
                                        from ac in res2.DefaultIfEmpty()
                                        where littleList.Contains(a.ProdNumber)
                                        select new { A = a, AB = ab, AC = ac };
                        if (scanQuery != null && scanQuery.Count() > 0)
                        {
                            var tmpList = scanQuery.ToList();
                            foreach (var item in tmpList.Select(q => new { target = q.A, group = q.AB }).Distinct().ToList())
                            {
                                var exQuery = tmpList.Where(q => q.A.ID == item.target.ID);
                                bool canUpdate = true;

                                //只要被排到小单组计划中的工单，而且工单又没有扫不防水和防水站的情况下，都将工单的流程改成小单组流程
                                if (exQuery != null && exQuery.Count() > 0)
                                {
                                    foreach (var tmpScan in exQuery)
                                    {
                                        if (tmpScan.AC != null && (tmpScan.AC.SiteInfoID == 12 || tmpScan.AC.SiteInfoID == 16 || tmpScan.AC.SiteInfoID == 18))
                                        { 
                                            canUpdate = false;
                                        }
                                    }
                                }
                                if (canUpdate)
                                {
                                    item.group.SiteGroupID = 18;
                                }
                            }
                        }
                    }

                    count = ctx.SaveChanges();
                }
            }
            else
            {
                throw new Exception("传入的排单计划为空！");
            }
            return count;
        }

        /// <summary>
        /// 按条件查询排单计划
        /// </summary>
        /// <param name="lineID">生产线ID</param>
        /// <param name="fillDayB">开始日期，针对排产日期</param>
        /// <param name="fillDayE">结束日期，针对排产日期</param>
        /// <param name="compDayB">开始日期，针对完成日期</param>
        /// <param name="compDayE">结束日期，针对完成日期</param>
        /// <param name="prodNo">工单号</param>
        /// <param name="isComp">是否已完成，0代表查询未完成；1代表查询已完成</param>
        /// <param name="isDel">是否已经撤销，0代表查询未撤销；1代表查询已撤销</param>
        /// <returns></returns>
        public List<ProdScheduleDTO> SearchProdSchedureForCondition(int lineID, DateTime? fillDayB, DateTime? fillDayE, DateTime? prodDayB, DateTime? prodDayE,
                                                                        DateTime? compDayB, DateTime? compDayE, string prodNo, int isComp, int isDel)
        {
            List<int> deptIds = bs.SelectUserDept();
            List<ProdScheduleDTO> resList = new List<ProdScheduleDTO>();
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.ProdSchedules
                            join b in ctx.TargetProdProcesses on a.ProdID equals b.ID into res1
                            from ab in res1.DefaultIfEmpty()
                            join c in ctx.ProdPointSMT on a.ProdNumber equals c.ProdNumber into res2
                            from ac in res2.DefaultIfEmpty()
                            select new { A = a, AB = ab, AC = ac };

                query = query.Where(res => res.AB.DeptId != 0 && deptIds.Contains(res.AB.DeptId));
                if (isDel == 1 || isDel == 0)
                {
                    query = query.Where(s => s.A.IsDel == isDel);
                }
                if (lineID > 0)
                {
                    query = query.Where(s => s.A.LineID == lineID);
                }
                if (fillDayB.HasValue == true)
                {
                    query = query.Where(s => DbFunctions.TruncateTime(s.A.FillDate) >= ((DateTime)fillDayB).Date);
                }
                if (fillDayE.HasValue == true)
                {
                    query = query.Where(s => DbFunctions.TruncateTime(s.A.FillDate) <= ((DateTime)fillDayE).Date);
                }
                if (prodDayB.HasValue == true)
                {
                    query = query.Where(s => DbFunctions.TruncateTime(s.A.ProdDate) >= ((DateTime)prodDayB).Date);
                }
                if (prodDayE.HasValue == true)
                {
                    query = query.Where(s => DbFunctions.TruncateTime(s.A.ProdDate) <= ((DateTime)prodDayE).Date);
                }
                if (compDayB.HasValue == true)
                {
                    query = query.Where(s => s.A.CompDate.HasValue == true && DbFunctions.TruncateTime(s.A.CompDate) >= ((DateTime)compDayB).Date);
                }
                if (compDayE.HasValue == true)
                {
                    query = query.Where(s => s.A.CompDate.HasValue == true && DbFunctions.TruncateTime(s.A.CompDate) <= ((DateTime)compDayE).Date);
                }
                if (prodNo != null && prodNo.Trim().Length > 0)
                {
                    query = query.Where(s => s.A.ProdNumber.Contains(prodNo));
                }
                if (isComp == 0)
                {
                    query = query.Where(s => s.A.IsComp != 1);
                }
                else if (isComp == 1)
                {
                    query = query.Where(s => s.A.IsComp == 1);
                }

                if (query != null && query.Count() > 0)
                {
                    foreach (var item in query.OrderBy(s => s.A.LineID).ThenBy(q => q.A.ID))
                    {
                        ProdScheduleDTO scheBean = new ProdScheduleDTO();
                        EntityTools.CopyEntity<ProdSchedule, ProdScheduleDTO>(item.A, ref scheBean);
                        if (item.AB != null)
                        {
                            scheBean.TargetProdProcess = item.AB;
                        }

                        scheBean.SmtPointTotal = 0;
                        if (item.AC != null)
                        {
                            scheBean.SmtPointTotal = item.AC.PointTotal ?? 0;
                        }
                        resList.Add(scheBean);
                    }
                }
            }

            return resList;
        }



        /// <summary>
        /// 按条件查询排单计划
        /// </summary>
        /// <param name="lineID">生产线ID</param>
        /// <param name="filldate">排单日期</param>
        /// <param name="prodNo">工单号</param>
        /// <param name="isComp">是否已完成</param>
        /// <returns></returns>
        public List<ProdScheduleDTO> SearchProdSchedureForCondition(int lineID, DateTime? filldate, string prodNo, int isComp)
        {
            List<ProdScheduleDTO> resList = new List<ProdScheduleDTO>();
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.ProdSchedules
                            join b in ctx.TargetProdProcesses on a.ProdID equals b.ID into res1
                            from ab in res1.DefaultIfEmpty()
                            select new { A = a, AB = ab };
                if (lineID > 0)
                {
                    query = query.Where(s => s.A.LineID == lineID);
                }
                if (filldate.HasValue == true)
                {
                    query = query.Where(s => DbFunctions.TruncateTime(s.A.FillDate) == ((DateTime)filldate).Date);
                }
                if (prodNo != null && prodNo.Trim().Length > 0)
                {
                    query = query.Where(s => s.A.ProdNumber.Contains(prodNo));
                }
                if (isComp == 0)
                {
                    query = query.Where(s => s.A.IsComp != 1);
                }
                else if (isComp == 1)
                {
                    query = query.Where(s => s.A.IsComp == 1);
                }

                if (query != null && query.Count() > 0)
                {
                    foreach (var item in query.OrderBy(s => s.A.LineID))
                    {
                        ProdScheduleDTO scheBean = new ProdScheduleDTO();
                        EntityTools.CopyEntity<ProdSchedule, ProdScheduleDTO>(item.A, ref scheBean);
                        if (item.AB != null)
                        {
                            scheBean.TargetProdProcess = item.AB;
                        }
                        resList.Add(scheBean);
                    }
                }
            }
            return resList;
        }


        public List<ProdScheduleDTO> SearchProdSchedureForCondition(List<int> lineList,List<string> prodList)
        {
            List<ProdScheduleDTO> resList = new List<ProdScheduleDTO>();
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.ProdSchedules
                            join b in ctx.TargetProdProcesses on a.ProdID equals b.ID into res1
                            from ab in res1.DefaultIfEmpty()
                            select new { A = a, AB = ab };
                if (lineList != null && lineList.Count > 0)
                {
                    query = query.Where(q => q.A.CompLineID.HasValue && lineList.Contains(q.A.CompLineID ?? 0));
                }
                if (prodList != null && prodList.Count > 0)
                {
                    query = query.Where(q => prodList.Contains(q.A.ProdNumber));
                }

                if (query != null && query.Count() > 0)
                {
                    foreach (var item in query.OrderBy(s => s.A.LineID))
                    {
                        ProdScheduleDTO scheBean = new ProdScheduleDTO();
                        EntityTools.CopyEntity<ProdSchedule, ProdScheduleDTO>(item.A, ref scheBean);
                        if (item.AB != null)
                        {
                            scheBean.TargetProdProcess = item.AB;
                        }
                        resList.Add(scheBean);
                    }
                }
            }
            return resList;
        }


        /// <summary>
        /// 根据ID查询排单计划
        /// </summary>
        /// <param name="ids">排单计划的ID</param>
        /// <returns></returns>
        public List<ProdScheduleDTO> SearchProdSchedureForID(List<int> ids)
        {
            List<ProdScheduleDTO> resList = new List<ProdScheduleDTO>();
            using (MesDB ctx = new MesDB())
            {
                var query = from a in ctx.ProdSchedules
                            join b in ctx.TargetProdProcesses on a.ProdID equals b.ID into res1
                            from ab in res1.DefaultIfEmpty()
                            where ids.Contains(a.ID)
                            select new { A = a, AB = ab };

                if (query != null && query.Count() > 0)
                {
                    foreach (var item in query.OrderBy(s => s.A.LineID))
                    {
                        ProdScheduleDTO scheBean = new ProdScheduleDTO();
                        EntityTools.CopyEntity<ProdSchedule, ProdScheduleDTO>(item.A, ref scheBean);
                        if (item.AB != null)
                        {
                            scheBean.TargetProdProcess = item.AB;
                        }
                        resList.Add(scheBean);
                    }
                }
            }
            return resList;
        }



        /// <summary>
        /// 删除排单计划
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public int DeleteProdScheduleForID(List<int> ids)
        {
            int count = 0;
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.ProdSchedules.Where(s => ids.Contains(s.ID));
                if (query != null && query.Count() > 0)
                {
                    List<ProdSchedule> scheList = query.ToList<ProdSchedule>();
                    var isCompQuery = scheList.Where(s => s.IsComp == 1);
                    if (isCompQuery != null && isCompQuery.Count() > 0)
                    {
                        throw new Exception("生产线：" + isCompQuery.First<ProdSchedule>().LineName + "\r\n" + "工单号：" + isCompQuery.First<ProdSchedule>().ProdNumber + "\r\n" + "该工单已完成，不能撤销！");
                    }
                    else
                    {
                        foreach (var item in scheList)
                        {
                            item.IsDel = 1;
                        }
                        count = ctx.SaveChanges();
                    }
                }
                else
                {
                    throw new Exception("数据库中没有找到相应的排单记录！");
                }
            }
            return count;
        }


        /// <summary>
        /// 更新工单排单计划的备注
        /// </summary>
        /// <param name="scheList"></param>
        /// <returns></returns>
        public int UpdateProdSchedure(List<ProdSchedule> scheList)
        {
            int count = 0;
            using (MesDB ctx = new MesDB())
            {
                foreach (var item in scheList)
                {
                    ctx.ProdSchedules.Attach(item);
                    ctx.Entry(item).Property(e => e.Remark).IsModified = true;
                    ctx.Entry(item).Property(e => e.RemarkPMC).IsModified = true;
                }
                count = ctx.SaveChanges();
            }
            return count;
        }


        /// <summary>
        /// 查询工单的包装计划的生产线
        /// </summary>
        /// <param name="prod"></param>
        /// <returns></returns>
        public string SearchPackProdLineForProd(string prod)
        {
            string prodLine = "";
            using (MesDB ctx = new MesDB())
            {
                var query = ctx.ProdSchedules.Where(s => s.ProdNumber == prod);
                if (query != null && query.Count() > 0)
                {
                    foreach(var item in query)
                    {
                        if (item.LineName.Contains("一线"))
                        {
                            prodLine = "一线";
                            break;
                        }
                        else if (item.LineName.Contains("二线"))
                        {
                            prodLine = "二线";
                            break;
                        }
                        else if (item.LineName.Contains("小单"))
                        {
                            prodLine = "小单组";
                            break;
                        }
                    }
                }
            }
            return prodLine;
        }


        public int UpdateScheduleCompLine(List<ProdSchedule> scheList)
        {
            int count = 0;
            DateTime tmpDay = this.GetCurrDateTime();
            using (MesDB ctx = new MesDB())
            {
                foreach (var item in scheList)
                {
                    if (item.ID == 0)
                    {
                        item.FillDate = new DateTime(1900, 1, 1);
                        item.ProdDate = new DateTime(1900, 1, 1);
                        item.LineID = 0;
                        item.LineCode = "";
                        item.LineName = "";
                        item.IsComp = 1;
                        item.CreateDate = tmpDay;
                        item.CreateUser = MainFrm.LoginUser.user_name;
                        ctx.ProdSchedules.Add(item);
                    }
                    else
                    {
                        var query = ctx.ProdSchedules.Where(q => q.ID == item.ID);
                        if (query != null && query.Count() > 0)
                        {
                            ProdSchedule tmpBean = query.First();
                            tmpBean.CompLineID = item.CompLineID;
                        }
                    }
                }

                count = ctx.SaveChanges();
            }
            return count;
        }
    }
}
